/**
 * ...
 * @author Axel Huizinga - axel@cunity.me
 */

//package globeOne;
package;

import flash.Boot;
import flash.display.DisplayObjectContainer;
import flash.events.Event;
import flash.filters.BitmapFilterType;
import flash.filters.BlurFilter;
import flash.filters.DropShadowFilter;
import flash.filters.GlowFilter;
import flash.filters.GradientGlowFilter;
import flash.geom.Rectangle;
import haxe.Timer;
import me.cunity.animation.FastTween;
import me.cunity.animation.sandy.STween;
import me.cunity.animation.TimeLine;
//import me.cunity.animation.sandy.TimeLine;
import me.cunity.animation.Transition;
import me.cunity.debug.Out;
import sandy.bounds.BBox;
import sandy.HaxeTypes;
import sandy.core.Scene3D;
import sandy.core.scenegraph.Camera3D;
import sandy.core.scenegraph.Group;
import sandy.core.scenegraph.Sprite2D;
import sandy.core.scenegraph.TransformGroup;
import sandy.materials.attributes.LightAttributes;
import sandy.materials.attributes.MaterialAttributes;
import sandy.materials.attributes.PhongAttributes;
import sandy.materials.ColorMaterial;
import sandy.primitive.Plane3D;
import sandy.primitive.Sphere;
import sandy.materials.Appearance;
import sandy.materials.BitmapMaterial;

import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.Lib;

class Planet extends Sprite
{
	var application:Main;
	var bg:Plane3D;
	var world:Scene3D;
	var planet:Sphere;
	var radius:Int;
	var rainbowRing:Ring;
	var ringRadius:Float;
	var tG:TransformGroup;
	var timeLine:TimeLine;
	var nextCall:Dynamic;
	var _lastSpin:Float;
	var _runTime:Float;
	var _spinCount:Int;
	var location:Dynamic;
	var zeroLength:Float;
	
	public function new(app:Main)
	{
		application = app;
		nextCall = app.nextCall;
		super();
	}
	
	public function init(w:Scene3D, loc:Dynamic = null)
	{
		world = w;
		name = 'Planet';
		tG = new TransformGroup('TgEarth');
		location = (loc == null ? { latitude:45, longitude:0 } : loc);
		_spinCount = 0;
		zeroLength = 90 + location.longitude;
		trace('zeroLength:' +zeroLength );
	}
	
	public function destroy()
	{
		STween.removeAllTweens();
		world.dispose();
	}
	
	public function draw()
	{
		//filters = [new GlowFilter(0x8888aa, 0.8, 10, 10)];
		// set up light attributes
		//var a:LightAttributes = new LightAttributes (true, 0.2);
		var a:PhongAttributes = new PhongAttributes (true, 0.3, 2);
		a.diffuse = 0.8;
		a.specular = 0.3;
		a.gloss = 1;
		// setup planet
		radius = 16;
		var quality = 25;
		planet = new Sphere ("Earth", radius, quality, quality);
		planet.rotateY = zeroLength;
		var m:BitmapMaterial = new BitmapMaterial(new Earth().bitmapData, new MaterialAttributes([a]));
		m.lightingEnable = true; 
		planet.appearance = new Appearance (m);
		
		tG.addChild(planet);
		rainbowRing = new Ring('rainbowRing', ringRadius, ringRadius);
		tG.addChild(rainbowRing.draw(true));
		tG.addChild(rainbowRing.draw());
		
		//return;
		/*rainbowRing.draw(
			[0xff0000, 0xff00ff, 0x0000ff, 0x00ffff, 0x00ff00, 0xffff00],
			[0.5, 0.5, 0.5, 0.5, 0.5, 0.5],
			[128, 133, 138, 143, 148, 153]
		);*/
		//tG.x = radius / 2;
		tG.rotateZ = 23.44;
		//tG.roll = 18;
		//tG.tilt = -15;
		tG.rotateX = -15;
		//tG.rotateY = 180;
		//tG.z = -5*radius;
		//var g:Group = new Group ("root"); 
		world.root.addChild (tG); 
		//trace('planet.z:' + planet.z + ' boundingBox:' + planet.boundingBox.toString());
		//world.light.color = 0x2222ff;
		world.light.setDirection (.5, 0.15, 1); 
		//setBg();
		world.render ();
		addEventListener(Event.ENTER_FRAME, spin);	
		//_runTime = Timer.stamp();

	}
	
	public function setBackground(w:Float, h:Float, app:Appearance=null)
	{
		ringRadius = h;
		
		if (!application.resizing)
		{
			bg = new Plane3D('outerSpace', h * 2,  w * 2 );
			bg.appearance = app;
			bg.z = 1000;			
			world.root.addChild(bg);
		}
		world.render();
		trace('bg.z:' + bg.z + ' boundingBox:' + bg.boundingBox.toString() + ' cam.z:' + world.camera.z);
		var d:Float = bg.getPosition(CoordinateSystem.CAMERA).getNorm();
		var bgBox: BBox = bg.boundingBox;
		var bgHeight: Float = Math.tan(world.camera.fov / 2) * d * 2;
		trace(bgHeight);
		//bg.scaleX = bg.scaleY = 0.5;
		trace('distance:' + d + ' fov:' + world.camera.fov  + ' objToFit.boundingBox.getHeight():' + bg.boundingBox.getHeight()  + ' viewport.height:' + world.camera.viewport.height);
		world.camera.fov = 2 * Math.atan2 ((h * 2) / 2, d) * (180 / Math.PI);
		trace('distance:' + d + ' fov:' + world.camera.fov + ' LOCAL:' + bg.getPosition(CoordinateSystem.LOCAL).toString() + ' CAMERA:' 
			+ bg.getPosition(CoordinateSystem.CAMERA).toString());
		//trace(planet.boundingBox.toString());

	}
	
	public function action()
	{
		var pp:Planet = this;
		//trace(Lib.current.name + ':' + parent.stage.root +' timeLine.next' + nextCall);
		//timeLine.dumpScreenPlay();
		/*if (application.screenPlay.nextKey != null)
		{
			timeLine.add(application.screenPlay.nextKey);
		}
		else
			rainbow();*/
		Timer.delay(function(){
			pp.go();
			//pp.zoomIn();
			//STween.add(pp.camFov, 2500, { values:[finalFov, cam.fov] }  , Transition.sineOut);
		}, 500);
		Timer.delay(function() {
			pp.setGlow();
		}, 2500);
	}	
	
	public function rainbow()
	{
		//trace('show...' + world.camera.z);
		rainbowRing.startShow(nextCall);
		/*timeLine.add(rainbowRing.startShow);
		if (application.screenPlay.nextKey != null)
		{
			timeLine.add(application.screenPlay.nextKey);
			timeLine.next();
		}	*/
		//timeLine.next();
	}	
	
	public function go()
	{ //nextCall = function() { trace('ok'); };
		//trace('...' + nextCall);
		if (world == null || world.camera == null)
			return;
		var finalDistance:Float = radius * 3 / Math.tan (world.camera.fov / 2 * (Math.PI / 180)) - tG.z;
		//trace(finalDistance + ' cam.z:' + world.camera.z);
		STween.add(goCam, 3500, { values:[-finalDistance, world.camera.z], onComplete:nextCall }  , Transition.sineOut);
	}
	
	function goCam(v:Float)
	{
		world.camera.z = v;
	}
	
	public function setGlow()
	{
		if (world == null || planet == null || planet.container == null)
			return;
		//planet.container.filters = [new GradientGlowFilter(0, 180, [0xffffff, 0xffffff,  0xffffff, 0x222280], [0.0, 0.2,  0.2, 0.8], [0, 32, 64, 255],
			//4, 4, 3, 3, BitmapFilterType.OUTER)];
			planet.container.filters = [new GradientGlowFilter(2, 160, [0xffffff, 0xffffff,  0xffffff, 0x222280], [0.0, 0.2,  0.2, 0.15], [0, 32, 64, 255],
			4, 4, 3, 3, BitmapFilterType.INNER),
			new DropShadowFilter(3, 160, 0xaaaacc, 0.33, 3, 3, 3, 3)];
	}
	
	function camFov(v:Float)
	{
		//trace(v);
		world.camera.fov = v;		
		//world.render();
	}
	
	function scalePlanet(v:Float)
	{
		//planet.scaleX = planet.scaleY = planet.scaleZ = v;
		//trace(v);
		tG.z = v;// - world.camera.z;
		//world.render();
	}
	
	function spin(evt:Event)
	{
		if (planet.rotateY > 360 + zeroLength)
		{
			//_spinCount++;
			removeEventListener(Event.ENTER_FRAME, spin);
			//planet.rotateY -= 357;
			//planet.rotateY = zeroLength + 3;
		}
		else
			planet.rotateY += 3;
		//if (world.camera.z < -160)
			//world.camera.z += 1;
		//if (world.camera.focalLength < -1 * world.camera.z)
			//world.camera.focalLength += 1;
		/*if (_spinCount > 0 && planet.rotateY - zeroLength >= finalYRot)
		{
			trace(planet.rotateY + ':' + finalYRot);
			removeEventListener(Event.ENTER_FRAME, spin);
		}*/
		world.render ();
	}
}

/*class Earth extends Bitmap {
	public function new () {
			super(null, null, true);
	}	
}*/
